/************************************************************************************************************************************
 *File     : diffuse.vs
 *Author   : cpzhang<chengpengzhang@gmail.com>
 *Date     : 2010-4-21
 *Platform : Windows XP, 32-bit, MSVC++ 2005, NVIDIA GeForce 9500 GT, 512M
 *Desc     : Vertex Shader that does diffuse lighting
***********************************************************************************************************************************/

/* global variables to store the view and projection transformation matrixs.
 * We initialize this variable from the application. */
matrix<float, 4, 4> viewMatrix;
matrix<float, 4, 4> viewProjectionMatrix;

/* global variables to store the ambient and diffuse materials.
 * We initialize this variable from the application. */
vector<float, 4> ambientMaterial;
vector<float, 4> diffuseMaterial;

/* global variables to store the light direction.
 * We initialize this variable from the application. */
static vector<float, 4> lightDirection;

/* global variable to store a blue color
 * We initialize this variable here in the shader
 * */
const vector<float, 4> diffuseLightIndensity = {0.0f, 0.0f, 1.0f, 1.0f};
const vector<float, 4> ambientLightIndensity = {0.0f, 0.0f, 0.2f, 1.0f}; 

/* input structure */
struct VS_INPUT
{
	vector<float, 4> position : POSITION;
	vector<float, 4> normal   : NORMAL;
};

/* output structure */
struct VS_OUTPUT
{
	vector<float, 4> position : POSITION;
	vector<float, 4> diffuse  : COLOR;
};

/* main entry point */
VS_OUTPUT main(VS_INPUT input)
{
	/* zero out output */
	VS_OUTPUT output = (VS_OUTPUT)0;

	/* transform  position to homogeneous clip space*/
	output.position = mul(input.position, viewProjectionMatrix);

	/* transform  normal and light to view space*/
	lightDirection.w = 0.0f;
	input.normal.w = 0.0f;
	lightDirection = mul(lightDirection, viewMatrix);
	input.normal = mul(input.normal, viewMatrix);
	
	/* compute the angle between light and normal */
	float s = dot(lightDirection, input.normal);
	if(s < 0.0f)
	{
		s = 0.0f;
	}
	/* compute the final vertex color */
	output.diffuse = ambientMaterial * ambientLightIndensity + s * diffuseMaterial * diffuseLightIndensity;

	/* return */
	return output;
}
